import requests
import pandas as pd
import json
from selenium import webdriver
import datetime
import time
import redis
import threading

from selenium.common import WebDriverException
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
from bs4 import BeautifulSoup as bs
from email.mime.multipart import MIMEMultipart
import urllib.parse
import configparser
from base_log import test_log2


config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8')  # 指定编码防止乱码:ml-citation{ref="3,7" data="citationList"}

web_location = r"D:\workSoftware\chromedriver"
from_name = config.get('DEFAULT', 'from_name')
web_url = config.get('DEFAULT', 'web_url')
date_time = config.getint('DEFAULT', 'date_time')
over_time = config.getint('DEFAULT', 'over_time')
date_file = config.get('DEFAULT', 'date_file')
error_number = config.get('DEFAULT', 'error_number')

redis_url = config.get('redis', 'host')
redis_port = config.getint('redis', 'port')
redis_pwd = config.get('redis', 'password')
expire_time = config.get('redis', 'expire_time')

from_addr = config.get('email', 'from_addr')
from_pwd = config.get('email', 'from_pwd')
smtp_addr = config.get('email', 'smtp_addr')
smtp_port = config.getint('email', 'smtp_port')

log_path = config.get('log', 'log_path')

a = test_log2(log_path+'log2.log')

pool = redis.ConnectionPool(host=redis_url, port=redis_port, password=redis_pwd, decode_responses=True)
r = redis.Redis(connection_pool=pool)

def getMaxid(wd, user_name, password ,email):
    print(f'getMaxid.......')
    time.sleep(10)
    wd.find_element(By.XPATH, value="//*[@id='menu_wmc']").click()
    time.sleep(20)
    window_handles = wd.window_handles
    wd.switch_to.window(window_handles[1])
    time.sleep(30)
    while 1==1:
        resp = getResponse(wd, wd.get_log('performance'), "&p=get_wmc_list_bet".format(password), user_name,email)
        # print(f'resp:{resp}')
        # cookies = wd.get_cookies()
        # print(f'cookies:{cookies}')
        time.sleep(15)

    # wd.get("chrome://settings/cookies")  # 访问内部页面AZXX
    # cookies = wd.execute_script("return document.cookie")  # 获取全部Cookie:ml-citation{ref="6,7" data="citationList"}
    # print(f'cookies：：{cookies}')


def send_web(user_name, password , email):
    print('sendweb.....')
    options = Options()
    caps = {
        "browserName": "chrome",
        'goog:loggingPrefs': {
            'performance': 'ALL',
            'driver': 'ALL'
        }  # 开启日志性能监听
    }
    for key, value in caps.items():
        options.set_capability(key, value)

    # 打开谷歌浏览器
    open = webdriver.ChromeOptions()
    open.add_argument(r"user-data-dir=./var/chrome-data")
    open.binary_location = web_location
    open.add_argument('--headless')
    open.add_argument("--auto-open-devtools-for-tabs")
    wd = webdriver.Chrome(options=options)

    wd.get(web_url)
    time.sleep(20)
    wd.maximize_window()
    wd.find_element(By.XPATH, "//*[@id='btn_C']").click()
    user = wd.find_element(by=By.XPATH, value="//*[@id='username']")
    pwd = wd.find_element(by=By.XPATH, value="//*[@id='pwd']")
    time.sleep(0.2)
    user.send_keys(user_name)
    pwd.send_keys(password)
    time.sleep(0.2)
    wd.find_element(By.XPATH, value="//*[@id='loginBtn']").click()
    time.sleep(10)
    getMaxid(wd, user_name, password,email)
    # wd.close()
    # wd.quit()

def filter_type(_type: str):
    types = [
        "application/javascript",
        "application/x-javascript",
        "text/css",
        "webp",
        "image/png",
        "image/gif",
        "image/jpeg",
        "image/x-icon",
        "application/octet-stream",
    ]
    if _type not in types:
        return True
    return False

## 获取请求header信息
def getResponse(wd,login_log, param_tag , user_name, email):
    apiURL = 'transform.php';
    # print('getResponse.....')
    for packet in login_log:
        message = json.loads(packet.get("message")).get("message")  # 获取message的数据
        if (
                message.get("method") != "Network.responseReceived"
        ):  # 如果method 不是 responseReceived 类型就不往下执行
            continue
        packet_type = (
            message.get("params").get("response").get("mimeType")
        )  # 获取该请求返回的type
        if not filter_type(_type=packet_type):  # 过滤type
            continue
        requestId = message.get("params").get(
            "requestId"
        )  # 唯一的请求标识符。相当于该请求的身份证
        url = message.get("params").get("response").get("url")  # 获取该请求url
        if not apiURL in url:  # 判断此url是否是我们需要的
            continue
        try:
            resp = wd.execute_cdp_cmd(
                "Network.getResponseBody", {"requestId": requestId}
            )  # selenium调用 cdp

            a.info(f'resp::{resp}')
            cookie = wd.execute_cdp_cmd(
                "Network.getCookies ", {"urls": ''}
            )  # selenium调用 cdp
            #  解析内容是否有信息，有则发发送
            if 'body' in resp:
                body = resp.get('body')

            wagers = extract_wagers(resp)
            for i in range(len(wagers)):
                print(f'wagers_[{i}]::{wagers[i]}')
                # 处理数据，并发送邮件。
                save_data(user_name, email, wagers[i])
            return resp
        except WebDriverException:  # 忽略异常
            pass

def extract_wagers(data_dict):
    try:
        # 确保body存在且是字典或字符串
        if 'body' not in data_dict:
            return None
        body = data_dict.get('body')
        if not body:
            return None

        # 如果body是字符串则解析为字典
        if isinstance(body, str):
            body = json.loads(body)

        # 检查wagers是否存在且非空
        wagers = body.get('wagers')
        if isinstance(wagers, list) and len(wagers) > 0:
            return wagers
        return None

    except (json.JSONDecodeError, AttributeError) as e:
        print(f"数据解析错误: {e}")
        return None

def clear_redis(user_name):
    data_key = "{}_data".format(user_name)
    ver_key = "{}_ver".format(user_name)
    header_key = "{}_header".format(user_name)
    retry_key = "{}_retry_number".format(user_name)
    r.delete(data_key)
    r.delete(ver_key)
    r.delete(header_key)
    r.delete(retry_key)



# def send_mail(to_adds, send_title, send_msg):
#     try:
#         # 创建MIME文本对象并添加内容
#         msg = MIMEText(send_msg)
#         msg['Subject'] = send_title
#         msg['From'] = formataddr([from_name, from_addr])
#         msg['To'] = ', '.join(to_adds)
#
#         # 连接到SMTP服务器并进行身份认证
#         server = smtplib.SMTP(smtp_addr, smtp_port)
#         server.starttls()
#         server.login(from_addr, from_pwd)
#
#         # 发送邮件
#         server.sendmail(from_addr, to_adds, msg.as_string())
#         print('邮件已成功发送！')
#     except Exception as e:
#         print('发送邮件时出现错误：', str(e))
#     finally:
#         # 关闭与SMTP服务器的连接
#         server.quit()

def send_mail(to_addr, send_title, send_msg):
    print(f'to_addr::{to_addr}  send_title::{send_title}  send_msg::{send_msg}')
    # 创建一个实例msg
    msg = MIMEMultipart()
    msg['From'] = formataddr([from_name, from_addr])
    msg['To'] = ', '.join(to_addr)
    msg['Subject'] = send_title
    # 邮件正文内容
    msg.attach(MIMEText(send_msg, 'html', 'utf-8'))
    try:
        smtpobj = smtplib.SMTP_SSL(smtp_addr)
        smtpobj.connect(smtp_addr, smtp_port)  # 建立连接--qq邮箱服务和端口号
        smtpobj.login(from_addr, from_pwd)  # 登录--发送者账号和口令
        smtpobj.sendmail(from_addr, to_addr, msg.as_string())
        print("邮件发送成功")
    except smtplib.SMTPException as e:
        print("无法发送邮件:", e)
    finally:
        # 关闭服务器
        smtpobj.quit()

def save_data(user, email, data):
    # key:账号：单号：地址
    print('save_data.....')
    fbk2 = data['TID']
    to_adds = []
    for i in range(len(email)):
        redis_key = "{}:{}:{}:".format(user, fbk2, email[i])
        if r.get(redis_key) is None:
            to_adds.append(email[i])

    if len(to_adds) < 1:
        print('save_data邮件已发送.....')
        return
    fbk1 = data['DATE'] + ' ' + data['TIME']
    td2str = data['NAME0']
    fbk7 = data['WAGERSTYPE']
    fbk8 = data['GT']
    # fbk10 = data['SHOWTEXT_LEAGUE']
    # fbk13 = data['SHOWTEXT_TEAM_NUM']
    # fbk11 = data['SHOWTEXT_TEAM']
    # fbk16 = data['SHOWTEXT_ORDER_TYPE_IORATIO']
    bs_info = bs(data['TNAME'], 'html.parser')

    find_li = bs_info.find_all('li', )
    if len(find_li) == 1:
        fbk10 = find_li[0].text
        fbk13 = ''
        fbk11 = ''
        fbk16 = ''
    else:
        fbk13 = find_li[0].text
        fbk11 = find_li[1].text
        fbk16 = find_li[2].text
        fbk10 = data['SHOWTEXT_LEAGUE']
    td5str = data['GOLD']

    html_template = """
       <p> 时间：{fbk1}</p>
       <p>会员：{td2str}</p>
       <p>单号：{fbk2}</p>
       <p>{fbk8}:{fbk7}</p>
        <p></p>
        <p>内容：</p>
        <p>{fbk10}</p>
        <p>{fbk13}</p>
        <p>{fbk11}</p>
        <p>{fbk16}</p>
        <p></p>
        <p>¥： {td5str}</p>
    """
    html_content = html_template.format(fbk1=fbk1, td2str=td2str, fbk2=fbk2, fbk7=fbk7, fbk8=fbk8, fbk10=fbk10,
                                        fbk11=fbk11, fbk13=fbk13, fbk16=fbk16, td5str=td5str)
    my_msg = "会员：" + td2str + "单号：" + fbk2
    send_mail(to_adds, my_msg, html_content)
    for i in to_adds:
        redis_key = "{}:{}:{}:".format(user, fbk2, i)
        r.set(redis_key, fbk2)


def update_date(number):
    df = pd.read_excel(date_file)
    row_index_to_modify = number - 1  # 转换为DataFrame的索引
    if row_index_to_modify < len(df):
        # 检查列名是否存在
        if '用户名' in df.columns and '密码' in df.columns:
            # 修改用户名和密码列的值
            df.at[row_index_to_modify, '状态'] = 3
            a.info(f"已修改行 {number} 的状态'")
        else:
            a.info(f"警告：文件中未找到'用户名'或'密码'列，无法修改。")
    else:
        a.info(f"警告：行号 {number} 超出范围，无法修改。")

    # 保存修改后的Excel文件
    output_file_path = 'account.xlsx'  # 输出文件名
    df.to_excel(output_file_path, index=False)  # index=False表示不保存行索引
    a.info(f"\n修改后的数据已保存到: {output_file_path}")

def get_login_info():
    df = pd.read_excel(date_file)
    # print("原始数据预览：")
    users = []
    for index, row in df.iterrows():  # 逐行迭代
        # print(f"\n行 {index} 数据：")
        user={}
        for col in df.columns:  # 遍历每一列
            if("序号" == col):
                user['id'] = row[col]
            elif("用户名"==col):
                user['name'] = row[col]
            elif("密码"==col):
                user['pwd'] = row[col]
            elif("邮箱"==col):
                user['email'] = row[col]
            elif("状态"==col):
                user['status'] = row[col]
            # print(f"{col}: {row[col]}")  # 输出列名和值
        users.append(user)
    return users

def main():
    df = get_login_info()
    for i in range(len(df)):
        name = df[i]['name']
        pwd = df[i]['pwd']
        email = df[i]['email'].split(",")
        a.info(f'name:{name} , password:{pwd} status:{df[i]["status"]} login web')
        send_web(name,pwd,email)



if __name__ == "__main__":
    main()
